<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      v-loading="formLoading"
    >
      <el-form-item label="软件名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入软件名称" />
      </el-form-item>

      <el-form-item label="软件描述" prop="description">
        <el-input v-model="formData.description" type="textarea" placeholder="请输入软件描述" />
      </el-form-item>
      <el-form-item label="开发商" prop="developer">
        <el-input v-model="formData.developer" placeholder="请输入开发商" />
      </el-form-item>
      <el-form-item label="软件类别" prop="category">
        <el-input v-model="formData.category" placeholder="请输入软件类别" />
      </el-form-item>
      <el-form-item label="更新内容" prop="updateContent">
        <el-input v-model="formData.updateContent" type="textarea" placeholder="请输入更新内容" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio
            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
            :key="dict.value"
            :label="dict.value"
          >
            {{ dict.label }}
          </el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="软件文件" prop="fileList">
        <el-tabs v-model="activeTab" type="card">
          <el-tab-pane
            v-for="dict in getStrDictOptions(DICT_TYPE.COMPO_SOFTWARE_FILE_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :name="dict.value"
          >
            <el-upload
              ref="uploadRef"
              v-model:file-list="uploadFiles[dict.value]"
              :action="uploadFileUrl"
              :auto-upload="true"
              :data="uploadData"
              :limit="1"
              :on-success="(response, file) => handleUploadSuccess(response, file, dict.value)"
              :on-error="handleUploadError"
              :on-exceed="handleExceed"
              :http-request="httpRequest"
              drag
            >
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">将文件拖到此处，或 <em>点击上传</em></div>
              <template #tip>
                <div class="el-upload__tip" style="color: #909399"
                  >支持各种格式文件，文件大小不超过10MB</div
                >
              </template>
            </el-upload>

            <el-form-item
              label="文件描述"
              :prop="`fileList.${getFileIndex(dict.value)}.description`"
            >
              <el-input
                v-model="getFile(dict.value).description"
                placeholder="请输入文件描述"
                type="textarea"
              />
            </el-form-item>
          </el-tab-pane>
        </el-tabs>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { SoftwareInfoApi, SoftwareInfoVO, SoftwareFileVO } from '@/api/compo/softwareInfo'
import { useUpload } from '@/components/UploadFile/src/useUpload'

/** 软件信息 表单 */
defineOptions({ name: 'SoftwareInfoForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const activeTab = ref('') // 当前激活的标签页
const uploadFileUrl =
  import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/ext/file/upload' // 上传文件的URL
const uploadData = ref({ path: '' }) // 上传文件的附加数据
const uploadRef = ref()
const uploadFiles = ref({}) // 每种类型的上传文件列表
const { httpRequest } = useUpload() // 使用自定义的上传请求处理

const formData = ref<{
  id?: number
  name?: string
  version?: string
  description?: string
  developer?: string
  category?: string
  status?: number
  updateContent?: string
  fileList: SoftwareFileVO[]
  requirementDoc?: SoftwareFileVO
  userManual?: SoftwareFileVO
  installationPackage?: SoftwareFileVO
}>({
  id: undefined,
  name: undefined,
  version: undefined,
  description: undefined,
  developer: undefined,
  category: undefined,
  status: undefined,
  updateContent: undefined,
  fileList: [],
  requirementDoc: undefined,
  userManual: undefined,
  installationPackage: undefined
})

// 获取文件在fileList中的索引
const getFileIndex = (fileType: string) => {
  const index = formData.value.fileList.findIndex((item) => item.fileType === fileType)
  if (index === -1) {
    formData.value.fileList.push({
      fileType,
      fileName: '',
      filePath: '',
      fileSize: 0,
      description: ''
    })
    return formData.value.fileList.length - 1
  }
  return index
}

// 获取或创建文件对象
const getFile = (fileType: string) => {
  const index = getFileIndex(fileType)
  return formData.value.fileList[index]
}

// 处理超出文件数量限制
const handleExceed = () => {
  message.warning('每种类型最多只能上传一个文件')
}

// 上传成功的处理
const handleUploadSuccess = (response: any, file: any, fileType: string) => {
  if (response.code === 0) {
    // 在上传成功后组装文件信息
    const fileObj = getFile(fileType)
    fileObj.fileName = file.name
    fileObj.filePath = response.data
    fileObj.fileSize = file.size
    message.success('文件上传成功')
  } else {
    message.error('文件上传失败')
  }
}

// 上传失败的处理
const handleUploadError = () => {
  message.error('文件上传失败，请重试')
}

const formRules = reactive({
  name: [{ required: true, message: '软件名称不能为空', trigger: 'blur' }],
  status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
})

const formRef = ref() // 表单 Ref

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()

  // 初始化上传文件列表
  uploadFiles.value = {}
  const fileTypes = getStrDictOptions(DICT_TYPE.COMPO_SOFTWARE_FILE_TYPE)
  fileTypes.forEach((dict) => {
    uploadFiles.value[dict.value] = []
  })

  // 设置默认激活的标签页
  if (fileTypes.length > 0) {
    activeTab.value = fileTypes[0].value
  }

  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      const response = await SoftwareInfoApi.getSoftwareInfo(id)
      // 确保formData.value被正确初始化
      if (!formData.value) {
        formData.value = {
          id: undefined,
          name: undefined,
          version: undefined,
          description: undefined,
          developer: undefined,
          category: undefined,
          status: undefined,
          updateContent: undefined,
          fileList: [],
          requirementDoc: undefined,
          userManual: undefined,
          installationPackage: undefined
        }
      }

      // 更新formData的值
      Object.assign(formData.value, response)

      // 确保fileList始终是一个数组
      formData.value.fileList = formData.value.fileList || []

      // 不再需要转换文件对象为数组形式，因为后端已经没有单独的文件字段

      // 仍需更新上传文件列表显示
      formData.value.fileList.forEach((file) => {
        if (file.fileType && file.fileName && file.filePath) {
          if (!uploadFiles.value[file.fileType]) {
            uploadFiles.value[file.fileType] = []
          }
          uploadFiles.value[file.fileType].push({
            name: file.fileName,
            url: file.filePath
          })
        }
      })
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()

  // 过滤掉没有上传文件的项
  formData.value.fileList = formData.value.fileList.filter((file) => file.fileName && file.filePath)

  // 准备提交数据
  const submitData: Partial<SoftwareInfoVO> = {
    id: formData.value.id || 0, // 新增时为0
    name: formData.value.name || '',
    version: formData.value.version || '1.0.0',
    description: formData.value.description || '',
    developer: formData.value.developer || '',
    category: formData.value.category || '',
    status: formData.value.status || 0,
    updateContent: formData.value.updateContent || ''
  }

  // 只有当文件列表有内容时才添加fileList字段
  if (formData.value.fileList.length > 0) {
    submitData.fileList = formData.value.fileList
  }

  // 提交请求
  formLoading.value = true
  try {
    if (formType.value === 'create') {
      await SoftwareInfoApi.createSoftwareInfo(submitData as SoftwareInfoVO)
      message.success(t('common.createSuccess'))
    } else {
      await SoftwareInfoApi.updateSoftwareInfo(submitData as SoftwareInfoVO)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    name: undefined,
    version: undefined,
    description: undefined,
    developer: undefined,
    category: undefined,
    status: undefined,
    updateContent: undefined,
    fileList: [],
    requirementDoc: undefined,
    userManual: undefined,
    installationPackage: undefined
  }

  // 清空上传文件
  if (uploadRef.value) {
    const refs = Array.isArray(uploadRef.value) ? uploadRef.value : [uploadRef.value]
    refs.forEach((ref) => {
      if (ref) ref.clearFiles()
    })
  }

  formRef.value?.resetFields()
}
</script>